package com.syc;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.syc.ext.CustomAutoGenerator;
import com.syc.ext.GenCodeService;
import com.syc.ext.MySqlTypeConvertCustom;
import org.apache.commons.lang.StringUtils;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;

public class MysqlGenerator {



	/**
	 * RUN THIS
	 */
	public static void main(String[] args) throws Exception {
		generatorCodeFile();
	}

	public static void generatorCodeFile() throws UnsupportedEncodingException {
		// 读取配置文件
		ResourceBundle rb = ResourceBundle.getBundle("config/subject");
		String codeStyle=rb.getString("style");
		String packagePath = rb.getString("file.packagePath");
		String packageValue = rb.getString("file.packageValue");
		String moduleName = rb.getString("file.moduleName");
		String tableName = rb.getString("manager.tableName");
		String tablePrefix = rb.getString("manager.tablePrefix");
		boolean needController = Boolean.parseBoolean(rb.getString("manager.needController"));
		boolean needImportExport = Boolean.parseBoolean(rb.getString("manager.controller.needImportExport"));
		String isFileOverride = rb.getString("manager.isFileOverride");
		String author = new String(rb.getString("file.author").getBytes("ISO-8859-1"),"UTF-8");
		String company = new String(rb.getString("file.company").getBytes("ISO-8859-1"),"UTF-8");
		//类名后缀（小写）
		String entity = rb.getString("class.entity");
		String form = rb.getString("class.form");
		String vo = rb.getString("class.vo");
		String page = rb.getString("class.page");
		String controller = rb.getString("class.controller");
		String mapper = rb.getString("class.mapper");
		//类名后缀（大写）
		String Entity=StringUtils.capitalize(entity);
		String Form=StringUtils.capitalize(form);
		String Vo=StringUtils.capitalize(vo);
		String Page=StringUtils.capitalize(page);
		String Controller=StringUtils.capitalize(controller);
		String Mapper=StringUtils.capitalize(mapper);


		String className = new GenCodeService().tableToJava(tableName, tablePrefix);
		String classname = StringUtils.uncapitalize(className);
		Map<String, Object> map = new HashMap<>();
		map.put("className", className);
		map.put("classname", classname);
		map.put("pathName", classname.toLowerCase());
		map.put("moduleName", moduleName);
		map.put("packageValue",packageValue);
		map.put("formName",className+Form);
		map.put("pageName",className+Page);
		map.put("voName",className+Vo);
		map.put("needImportExport",needImportExport);
		map.put("needController",needController);
		if(StringUtils.isNotEmpty(moduleName)){
			map.put("formPackageValue",packageValue+"."+form+"."+moduleName);
			map.put("pagePackageValue",packageValue+"."+page+"."+moduleName);
			map.put("voPackageValue",packageValue+"."+vo+"."+moduleName);
		}else {
			map.put("formPackageValue",packageValue+"."+form);
			map.put("pagePackageValue",packageValue+"."+page);
			map.put("voPackageValue",packageValue+"."+vo);
		}
		String resultPackageValue=packageValue+"."+entity+".base";
		String resultPackagePath=packagePath+"/"+entity+"/base";
		map.put("resultPackageValue",resultPackageValue);
		map.put("company",company);
		map.put("codeStyle",codeStyle);

		// 代码生成器
		CustomAutoGenerator mpg = new CustomAutoGenerator(map);
		// 全局配置
		GlobalConfig gc = new GlobalConfig();
		String projectPath = System.getProperty("user.dir");
		gc.setAuthor(author);
		gc.setDateType(DateType.SQL_PACK);
		gc.setOpen(false);
		gc.setSwagger2(false);
		gc.setBaseResultMap(true);
		gc.setBaseColumnList(true);
		gc.setServiceName(className + "Service");
		gc.setFileOverride(Boolean.parseBoolean(isFileOverride));
		mpg.setGlobalConfig(gc);

		// 数据源配置
		DataSourceConfig dsc = new DataSourceConfig();
		dsc.setUrl(rb.getString("jdbc.url"));
		// dsc.setSchemaName("public");
		dsc.setDriverName("com.mysql.cj.jdbc.Driver");
		dsc.setUsername(rb.getString("jdbc.username"));
		dsc.setPassword(rb.getString("jdbc.password"));
		dsc.setTypeConvert(new MySqlTypeConvertCustom());
		mpg.setDataSource(dsc);

		// 包配置
		PackageConfig pc = new PackageConfig();
		// pc.setModuleName(moduleName);
		pc.setParent(packageValue);
		if(StringUtils.isNotEmpty(moduleName)){
			pc.setService("service." + moduleName);
			pc.setServiceImpl("service.impl." + moduleName);
			pc.setController(controller+"." + moduleName);
			pc.setMapper(mapper+"." + moduleName);
			pc.setEntity(entity+"." + moduleName);
		}else {
			pc.setService("service");
			pc.setServiceImpl("service.impl");
			pc.setController(controller);
			pc.setMapper(mapper);
			pc.setEntity(entity);
		}
		mpg.setPackageInfo(pc);

		// 自定义配置
		InjectionConfig cfg = new InjectionConfig() {
			@Override
			public void initMap() {
			}
		};
		List<FileOutConfig> focList = new ArrayList<>();
		focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {

			@Override
			public String outputFile(TableInfo tableInfo) {
				tableInfo.setMapperName(className + Mapper);
				tableInfo.setEntityName(className + Entity);
				return projectPath + "/src/main/resources/"+pc.getMapper().replace(".","/")+"/" + className
						+ Mapper + StringPool.DOT_XML;
			}
		});
		focList.add(new FileOutConfig("/templates/service.java.ftl") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				tableInfo.setServiceName(className + "Service");
				tableInfo.setEntityName(className + Entity);
				return projectPath + "/src/main/java/"+packagePath+"/"+pc.getService().replace(".","/")+"/" + className
						+ "Service" + StringPool.DOT_JAVA;
			}
		});
		focList.add(new FileOutConfig("/templates/serviceImpl.java.ftl") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				tableInfo.setServiceImplName(className + "ServiceImpl");
				tableInfo.setEntityName(className + Entity);
				return projectPath + "/src/main/java/"+packagePath+"/"+pc.getServiceImpl().replace(".","/")+"/" + className
						+ "ServiceImpl" + StringPool.DOT_JAVA;
			}
		});
		if (needController) {
			focList.add(new FileOutConfig("/templates/controller.java.ftl") {
				@Override
				public String outputFile(TableInfo tableInfo) {
					tableInfo.setControllerName(className + Controller);
					tableInfo.setEntityName(className + Entity);
					return projectPath + "/src/main/java/"+packagePath+"/"+pc.getController().replace(".","/")+"/"
							+ className + Controller + StringPool.DOT_JAVA;
				}
			});
			focList.add(new FileOutConfig("/templates/form.java.ftl") {
				@Override
				public String outputFile(TableInfo tableInfo) {
					tableInfo.setEntityName(className + Entity);
					if(StringUtils.isNotEmpty(moduleName)){
						return projectPath + "/src/main/java/"+packagePath+"/"+form+"/" + moduleName + "/" + className
								+ Form + StringPool.DOT_JAVA;
					}else {
						return projectPath + "/src/main/java/"+packagePath+"/"+form+"/" + className
								+ Form + StringPool.DOT_JAVA;
					}
				}
			});
			focList.add(new FileOutConfig("/templates/page.java.ftl") {
				@Override
				public String outputFile(TableInfo tableInfo) {
					tableInfo.setEntityName(className + Entity);
					if(StringUtils.isNotEmpty(moduleName)){
						return projectPath + "/src/main/java/"+packagePath+"/"+page+"/" + moduleName + "/" + className
								+ Page + StringPool.DOT_JAVA;
					}else {
						return projectPath + "/src/main/java/"+packagePath+"/"+page+"/" + className
								+ Page + StringPool.DOT_JAVA;
					}
				}
			});
		}
		focList.add(new FileOutConfig("/templates/mapper.java.ftl") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				tableInfo.setEntityName(className + Entity);
				tableInfo.setMapperName(className + Mapper);
				return projectPath + "/src/main/java/"+packagePath+"/"+pc.getMapper().replace(".","/")+"/" + className
						+ Mapper + StringPool.DOT_JAVA;
			}
		});
		focList.add(new FileOutConfig("/templates/entity.java.ftl") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				tableInfo.setEntityName(className + Entity);
				return projectPath + "/src/main/java/"+packagePath+"/"+pc.getEntity().replace(".","/")+"/" + className
						+ Entity + StringPool.DOT_JAVA;
			}
		});
		focList.add(new FileOutConfig("/templates/vo.java.ftl") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				tableInfo.setEntityName(className + Entity);
				if(StringUtils.isNotEmpty(moduleName)){
					return projectPath + "/src/main/java/"+packagePath+"/"+vo+"/" + moduleName + "/" + className
							+ Vo + StringPool.DOT_JAVA;
				}else {
					return projectPath + "/src/main/java/"+packagePath+"/"+vo+"/" + className
							+ Vo + StringPool.DOT_JAVA;
				}
			}
		});
		cfg.setFileOutConfigList(focList);
		mpg.setCfg(cfg);
		// 关闭默认 xml 生成，调整生成 至 根目录
		mpg.setTemplate(new TemplateConfig().setXml(null)
				// 自定义模板配置，模板可以参考源码 /mybatis-plus/src/main/resources/template 使用 copy
				// 至您项目 src/main/resources/template 目录下，模板名称也可自定义如下配置：
				.setController(null)
				.setEntity(null)
				.setMapper(null)
				.setXml(null)
				.setService(null)
				.setServiceImpl(null));

		// 策略配置
		StrategyConfig strategy = new StrategyConfig();
		strategy.setNaming(NamingStrategy.underline_to_camel);
		strategy.setColumnNaming(NamingStrategy.underline_to_camel);
		strategy.setEntityTableFieldAnnotationEnable(true);
		strategy.setEntityLombokModel(true);
		strategy.setInclude(tableName);
		strategy.setLogicDeleteFieldName("delFlag");
		strategy.setControllerMappingHyphenStyle(true);
		mpg.setStrategy(strategy);
		// 选择 freemarker 引擎需要指定如下加，注意 pom 依赖必须有！
		mpg.execute();
		if("kys".equals(codeStyle) || "ca".equals(codeStyle)){
			generatorKysResult(projectPath,resultPackageValue,resultPackagePath);
		}else {
			generatorResult(projectPath,resultPackageValue,resultPackagePath);
		}
	}

	public static void generatorResult(String projectPath,String packageValue,String packagePath){
		File originResult=new File(projectPath+"/src/main/java/com/syc/ext/Result.java");
		File newResult=new File(projectPath+"/src/main/java/"+packagePath+"/Result.java");
		FileUtil.copy(originResult,newResult,true);
		List<String> lines = FileUtil.readLines(newResult, StandardCharsets.UTF_8);
		lines.set(0, String.format("package %s;", packageValue));
		FileUtil.writeLines(lines,newResult,StandardCharsets.UTF_8);
	}

	public static void generatorKysResult(String projectPath,String packageValue,String packagePath){
		File originResult=new File(projectPath+"/src/main/java/com/syc/ext/IzhResponseBody.java");
		File newResult=new File(projectPath+"/src/main/java/"+packagePath+"/IzhResponseBody.java");
		FileUtil.copy(originResult,newResult,true);
		List<String> lines = FileUtil.readLines(newResult, StandardCharsets.UTF_8);
		lines.set(0, String.format("package %s;", packageValue));
		FileUtil.writeLines(lines,newResult,StandardCharsets.UTF_8);
		File originUtil=new File(projectPath+"/src/main/java/com/syc/ext/ResponseUtil.java");
		File newUtil=new File(projectPath+"/src/main/java/"+packagePath+"/ResponseUtil.java");
		FileUtil.copy(originUtil,newUtil,true);
		List<String> utilLines = FileUtil.readLines(newUtil, StandardCharsets.UTF_8);
		utilLines.set(0, String.format("package %s;", packageValue));
		FileUtil.writeLines(utilLines,newUtil,StandardCharsets.UTF_8);
	}

}